package ch.abcm.remsmobile.REMSMobile.network.networkutils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.util.Log;

public class SSIDScanner {

    private static final String TAG = "SSIDScanner";
    private WifiManager wifiManager;

    public SSIDScanner(Context context) {
        this.wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    }

    public boolean isAccesspointActive() {
        Method[] wmMethods = wifiManager.getClass().getDeclaredMethods();
        for (Method isWifiApEnabledmethod : wmMethods) {
            if (isWifiApEnabledmethod.getName().equals("isWifiApEnabled")) {
                try {
                    boolean accesspointIsActive =  (Boolean) isWifiApEnabledmethod.invoke(wifiManager);
                    Log.d(TAG, "Accesspoint is active: "+ accesspointIsActive);
                    return accesspointIsActive;
                } catch (IllegalArgumentException e) {
                    Log.e(TAG, "IllegalArgumentException: " + e.getMessage());
                } catch (IllegalAccessException e) {
                    Log.e(TAG, "IllegalAccessException: " + e.getMessage());
                } catch (InvocationTargetException e) {
                    Log.e(TAG, "InvocationTargetException: " + e.getMessage());
                }
            }
        }
        return false;
    }

    public boolean isDeviceConnectedToSSID(String ssid) {
        String connectedSSID = wifiManager.getConnectionInfo().getSSID();
        int gatewayIP = wifiManager.getDhcpInfo().gateway;
        Log.d(TAG, "GatewayIP is: " + gatewayIP);
        Log.d(TAG, "Connected SSID: " + connectedSSID);
        // Use GatewayIP, SSID does not work confidable
        if (gatewayIP == 0) {
            return false;
        }
        connectedSSID = connectedSSID.replace("\"", "");
        if (connectedSSID.equalsIgnoreCase(ssid)) {
            return true;
        }
        return false;
    }

    public boolean isWifiWithSSIDAvailable(String ssid) {
        Log.d(TAG, "Start scanning SSIDs");
        List<ScanResult> scanResults = wifiManager.getScanResults();
        for (ScanResult scanResult : scanResults) {
            String tmpSSID = scanResult.SSID;
            if (tmpSSID != null && tmpSSID.equalsIgnoreCase(ssid)) {
                Log.d(TAG, "Found Network with SSID: " + ssid);
                return true;
            }
        }
        return false;
    }

    public void enableWiFi() {
        if (!wifiManager.isWifiEnabled()) {
            Log.d(TAG, "Enable WiFi");
            boolean isEnabled = wifiManager.setWifiEnabled(true);
            if (isEnabled) {
                Log.e(TAG, "setWifiEnabled failed");
            }
        }
        Log.d(TAG, "Sart Scanning for Networks");
        wifiManager.startScan();
    }

    public ArrayList<String> getAvailableSSIDs() {
        return getAvailableSSIDs(false);
    }

    public ArrayList<String> getAvailableSSIDs(boolean logDetails) {

        ArrayList<String> ssids = new ArrayList<String>();
        Log.d(TAG, "Start scanning SSIDs");
        List<ScanResult> scanResults = wifiManager.getScanResults();
        Log.d(TAG, "Found " + scanResults.size() + " Networks");
        Log.d(TAG, "ScannResults " + scanResults);

        for (ScanResult scanResult : scanResults) {
            if (logDetails) {
                logScannresultDetails(scanResult);
            }
            ssids.add(scanResult.SSID);
        }
        return ssids;
    }

    private void logScannresultDetails(ScanResult scanResult) {
        String msg = "";
        msg += "BSSID=" + scanResult.BSSID;
        msg += " capabilities=" + scanResult.capabilities;
        msg += " frequency=" + scanResult.frequency;
        msg += " level=" + scanResult.level;
        String ssid = " SSID=" + scanResult.SSID;
        msg += ssid;
        Log.d(TAG + "_SSID", ssid);
        Log.i(TAG, msg);
    }
}
